package org.hepeng.workx.spring.cloud.netflix.zuul.filter;

import org.apache.commons.lang3.ArrayUtils;
import org.hepeng.workx.spring.cloud.netflix.zuul.ZuulResponseHeader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

import java.util.ArrayList;
import java.util.List;

/**
 * @author he peng
 */

@Configuration
public class ZuulResponseHeaderConfiguration implements ImportAware {

    @Autowired
    private ApplicationContext applicationContext;

    private static final List<ZuulResponseWriterHeaderFilter.HeaderWriter> HEADER_WRITERS = new ArrayList<>();

    @Override
    public void setImportMetadata(AnnotationMetadata importMetadata) {
        AnnotationAttributes annotationAttrs = AnnotationAttributes.fromMap(
                importMetadata.getAnnotationAttributes(ZuulResponseHeader.class.getName(), false));
        Class<?>[] headerWriters = annotationAttrs.getClassArray("headerWriters");
        if (ArrayUtils.isNotEmpty(headerWriters)) {
            try {
                for (Class<?> headerWriter : headerWriters) {
                    Object bean;
                    try {
                        bean = this.applicationContext.getBean(headerWriter);
                        HEADER_WRITERS.add((ZuulResponseWriterHeaderFilter.HeaderWriter) bean);
                    } catch (Throwable t) {
                        bean = headerWriter.newInstance();
                    }
                    HEADER_WRITERS.add((ZuulResponseWriterHeaderFilter.HeaderWriter) bean);
                }
            } catch (Throwable t) {
                throw new RuntimeException(t);
            }
        }
    }

    @Bean
    public ZuulResponseWriterHeaderFilter zuulInternalResponseWriterHeaderFilter() {
        return new ZuulResponseWriterHeaderFilter(HEADER_WRITERS);
    }
}
